#include "gd32f1x0.h"
#include "soft_iic.h"

/*以下内容为软件定义IIC，不需要进行修改*/
void soft_iic_init(void)
{
    unsigned char ii = 0;
    GPIO_INIT();
    DELAY(500);
    SCL_SET();
    for (ii = 0; ii < 9; ii++)
    {
        SCL_RESET();
        DELAY(16 * DELAYFACT);
        SCL_SET();
        DELAY(16 * DELAYFACT);
    }
}

void soft_iic_start(void)
{
    SDA_OUT();
    SDA_SET();
    SCL_SET();
    DELAY(16 * DELAYFACT);
    SDA_RESET();
    DELAY(4 * DELAYFACT);
    SCL_RESET();
    DELAY(2 * DELAYFACT);
}

void soft_iic_stop(void)
{
    SCL_RESET();
    SDA_OUT();
    SDA_RESET();
    DELAY(4 * DELAYFACT);
    SCL_SET();
    DELAY(4 * DELAYFACT);
    SDA_SET();
    DELAY(2 * DELAYFACT);
}

unsigned char soft_iic_wait_ack(void)
{
    unsigned short int retry = 0;
    SCL_RESET();
    SDA_OUT();
    SDA_SET();
    SDA_IN();
    DELAY(4 * DELAYFACT);
    SCL_SET();
    DELAY(1 * DELAYFACT);
    while (SDA_GET() == 1)
    {
        retry++;
        if (retry > 500)
            break;
    }
    if (SDA_GET() == 0)
    {
        SCL_RESET();
        DELAY(4 * DELAYFACT);
        return 0;
    }
    else
    {
        soft_iic_stop();
        return 1;
    }
}

void soft_iic_ack(unsigned char ack_nack)
{
    SCL_RESET();
    SDA_OUT();
    SDA_BIT(ack_nack);
    DELAY(2 * DELAYFACT);
    SCL_SET();
    DELAY(4 * DELAYFACT);
    SCL_RESET();
    DELAY(4 * DELAYFACT);
}

void soft_iic_writeByte(unsigned char val)
{
    int i;
    SCL_RESET();
    DELAY(1);
    SDA_OUT();
    for (i = 0; i < 8; i++)
    {
        SDA_BIT(val & 0x80);
        DELAY(2 * DELAYFACT);
        SCL_SET();
        DELAY(2 * DELAYFACT);
        SCL_RESET();
        DELAY(2 * DELAYFACT);
        val <<= 1;
    }
}
unsigned char soft_iic_readByte(unsigned char ack)
{
    unsigned char i, data;
    SCL_RESET();
    SDA_IN();
    for (i = 0, data = 0; i < 8; i++)
    {
        data <<= 1;
        SCL_SET();
        hwl_delay_us(2* DELAYFACT);
        data |= SDA_GET();
        SCL_RESET();
        hwl_delay_us(2 * DELAYFACT);
    }
    soft_iic_ack(ack);
    return data;
}
